package cn.lystudio.rohmtimeopwide_background_v11.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ConcurrentHashSet;
import cn.hutool.core.util.StrUtil;
import cn.lystudio.rohmtimeopwide_background_v11.entity.dto.MachineDTO;
import cn.lystudio.rohmtimeopwide_background_v11.entity.dto.RecordDTO;
import cn.lystudio.rohmtimeopwide_background_v11.entity.po.RecordPO;
import cn.lystudio.rohmtimeopwide_background_v11.entity.po.UsersPO;
import cn.lystudio.rohmtimeopwide_background_v11.entity.vo.OpUserFullNameVO;
import cn.lystudio.rohmtimeopwide_background_v11.entity.vo.TimeRecord4ExcelVO;
import cn.lystudio.rohmtimeopwide_background_v11.mapper.RecordPOMapper;
import cn.lystudio.rohmtimeopwide_background_v11.mapper.UsersPOMapper;
import cn.lystudio.rohmtimeopwide_background_v11.service.MachineService;
import cn.lystudio.rohmtimeopwide_background_v11.service.RecordService;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Set;

@Service
@Slf4j
@DS("master")

public class RecordServiceImpl implements RecordService {
    @Resource
    private RecordPOMapper recordPOMapper;
    @Resource
    private UsersPOMapper usersPOMapper;
    private MachineService machineService;

    @Autowired
    @Lazy
    public void setMachineService(MachineService machineService) {
        this.machineService = machineService;
    }

    @Override
    public List<RecordDTO> getAll(String userCode,
                                  String machineNo,
                                  List<String> recordTypeList,
                                  String searchStartTime,
                                  String searchEndTime,
                                  String LotNo,
                                  String AQRNo,
                                  String otherKeywords) {
        // 1. 获取所有设备
        List<MachineDTO> machineDTOList = machineService.getAll(null);
        // 1.1 组装machineNoList
        Set<String> machineNoList = new ConcurrentHashSet<>();
        CollUtil.forEach(machineDTOList.iterator(), (machineDTO, index) -> {
            machineNoList.add(machineDTO.getMachine().getMachineNo());
        });
        // 2.获取所有记录
        LambdaQueryWrapper<RecordPO> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(RecordPO::getMachineNo, machineNoList)
                // 关键字搜索
                .and(StrUtil.isNotEmpty(userCode), i -> {
                    i.like(RecordPO::getUserCode, userCode)
                            .or()
                            .like(RecordPO::getUserCodeEnd, userCode);
                })
                .like(StrUtil.isNotEmpty(machineNo), RecordPO::getMachineNo, machineNo)
                .like(StrUtil.isNotEmpty(LotNo), RecordPO::getRecordLotInfo, LotNo)
                .like(StrUtil.isNotEmpty(AQRNo), RecordPO::getRecordAQRInfo, AQRNo)
                .in(CollUtil.isNotEmpty(recordTypeList), RecordPO::getRecordType, recordTypeList)
                .and(StrUtil.isNotEmpty(searchStartTime) && StrUtil.isNotEmpty(searchEndTime), i -> {
                    i.between(RecordPO::getRecordTimeBeginDT, searchStartTime, searchEndTime)
                            .or()
                            .between(RecordPO::getRecordTimeEndDT, searchStartTime, searchEndTime);
                })
                .and(StrUtil.isNotEmpty(otherKeywords), i -> {
                    i.like(RecordPO::getRecordName, otherKeywords)
                            .or()
                            .like(RecordPO::getRecordPart, otherKeywords)
                            .or()
                            .like(RecordPO::getRecordResult, otherKeywords)
                            .or()
                            .like(RecordPO::getAbnormalHandler, otherKeywords)
                            .or()
                            .like(RecordPO::getRecordRemark, otherKeywords)
                            .or()
                            .like(RecordPO::getRecordVerify, otherKeywords);
                })
                .orderByDesc(RecordPO::getRecordTimeBeginDT);
        List<RecordPO> recordPOList = recordPOMapper.selectList(wrapper);
        if (CollUtil.isEmpty(recordPOList)) return null;

        // 3.获取所有人员信息
        List<UsersPO> usersPOList = usersPOMapper.selectList(null);

        // 4.组装view层数据
        List<RecordDTO> recordDTOList = CollUtil.list(false);
        CollUtil.forEach(recordPOList.iterator(), (record, index) -> {
            RecordDTO recordDTO = new RecordDTO();
            recordDTO.setRecord(record);
            if (StrUtil.isNotEmpty(record.getMachineNo())) {
                recordDTO.setMachine(
                        CollUtil.findOne(machineDTOList, machine -> {
                            return record.getMachineNo().equals(machine.getMachine().getMachineNo());
                        })
                );
            }
            if (StrUtil.isNotEmpty(record.getUserCode())) {
                recordDTO.setStartUser(
                        CollUtil.findOne(usersPOList, user -> {
                            return record.getUserCode().equals(user.getUserCode());
                        })
                );
            }

            if (StrUtil.isNotEmpty(record.getUserCodeEnd())) {
                recordDTO.setEndUser(
                        CollUtil.findOne(usersPOList, user -> {
                            return record.getUserCodeEnd().equals(user.getUserCode());
                        })
                );
            }
            recordDTOList.add(recordDTO);
        });
        // 5.过滤数据
        CollUtil.removeNull(recordDTOList);
        return recordDTOList;
    }

    @Override
    public int delRecord(Integer recordID) {
        return recordPOMapper.deleteById(recordID);
    }

    /**
     * 为主页表格准备数据
     */
    @Override
    public List<RecordDTO> getDailyData4Console(String machineNo, String dailyStart, String dailyEnd) {
        //1.获取数据
        LambdaQueryWrapper<RecordPO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RecordPO::getMachineNo, machineNo)
                .ge(RecordPO::getRecordTimeBeginDT, dailyStart)
                .lt(RecordPO::getRecordTimeBeginDT, dailyEnd)
                .orderByAsc(RecordPO::getRecordTimeBeginDT);
        List<RecordPO> recordPOList = recordPOMapper.selectList(wrapper);
        if (CollUtil.isEmpty(recordPOList)) return null;
        // 2.获取所有用户
        List<UsersPO> userAll = usersPOMapper.selectList(null);

        // 组装数据
        List<RecordDTO> recordDTOList = CollUtil.list(false);
        CollUtil.forEach(recordPOList.iterator(), (record, index) -> {
            RecordDTO recordDTO = new RecordDTO();
            recordDTO.setRecord(record);
            recordDTO.setStartUser(
                    CollUtil.findOne(userAll, user -> user.getUserCode().equals(record.getUserCode()))
            );
            recordDTO.setEndUser(
                    CollUtil.findOne(userAll, user -> user.getUserCode().equals(record.getUserCodeEnd()))
            );
            recordDTOList.add(recordDTO);
        });
        return recordDTOList;
    }

    @Override
    public int AppInsertRecord(RecordPO recordPO) {
        return recordPOMapper.insert(recordPO);
    }

    @Override
    public List<RecordPO> getUnfinishedRecord(String machineNo) {
        LambdaQueryWrapper<RecordPO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RecordPO::getMachineNo, machineNo)
                .and(i -> i.eq(RecordPO::getUserCodeEnd, "")
                        .or()
                        .isNull(RecordPO::getUserCodeEnd)
                );
        return recordPOMapper.selectList(wrapper);
    }

    @Override
    public int uptUnfinishedRecord(RecordPO recordPO) {
        LambdaQueryWrapper<RecordPO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RecordPO::getMachineNo, recordPO.getMachineNo())
                .eq(RecordPO::getRecordType, recordPO.getRecordType())
                .eq(RecordPO::getRecordName, recordPO.getRecordName())
                .lt(RecordPO::getRecordTimeBeginDT,recordPO.getRecordTimeEndDT())
                .and(i -> i.eq(RecordPO::getUserCodeEnd, "")
                        .or()
                        .isNull(RecordPO::getUserCodeEnd)
                );
        return recordPOMapper.update(recordPO,wrapper);
    }

    @Override
    public RecordPO getRecordByRecordID(int recordID) {
        return recordPOMapper.selectById(recordID);
    }

    @Override
    public int uptRecordByRecordID(RecordPO recordPO) {
        return recordPOMapper.updateById(recordPO);
    }

    @Override
    public List<TimeRecord4ExcelVO> getTimeRecord(String machineNo,String beginDate, String endDate) {
        return recordPOMapper.getTimeRecord4ExcelVO(machineNo, beginDate, endDate);
    }

    @Override
    public OpUserFullNameVO getOpUserFullName(String machineNo, String beginDate, String endDate) {
        return recordPOMapper.getOpUserFullName(machineNo, beginDate, endDate);
    }
}
